package xyz.thoughtset.viewer.executor.core.base;

import lombok.Data;
import org.apache.ibatis.parsing.XNode;
import org.springframework.util.MultiValueMap;
import org.springframework.util.MultiValueMapAdapter;
import org.springframework.util.StringUtils;
import xyz.thoughtset.viewer.executor.core.base.DataNode;

import java.util.*;

@Data
public class ResultContext {
    private DataNode node;
    private HashMap<String,Map> keyDatas = new HashMap<>();
    private List dataList = new ArrayList<>();
    private static final MultiValueMap<String,String> keysMap = new MultiValueMapAdapter<>(new HashMap<>());

    public ResultContext(DataNode dataNode){
        this.node = dataNode;
    }

    public void putData(Map data){
        if (node == null) {
            dataList.add(data);
            return;
        }
        String keyStr = buildKeyStr(data);
        if (!keyDatas.containsKey(keyStr)){
            keyDatas.put(keyStr,data);
            dataList.add(data);
            return  ;
        }
        Map existingData = keyDatas.get(keyStr);
        mergeData(existingData,data,node,keyStr);
        return ;
    }

//    public void putRsVal(Object data,String rowKey){
//        if (r)
//        if (node == null) dataList.add(data);
//        String keyStr = buildKeyStr(data);
//        if (!keyDatas.containsKey(keyStr)){
//            keyDatas.put(keyStr,data);
//            dataList.add(data);
//            return  ;
//        }
//        Map existingData = keyDatas.get(keyStr);
//        mergeData(existingData,data,node,keyStr);
//        return ;
//    }

    private String buildKeyStr(Map data){
        return buildKeyStr(data,node);
    }
    private String buildKeyStr(Map data,DataNode node){
        StringBuilder keyBuilder = new StringBuilder();
        for (String k : node.getKeyColumnNames()) {
            Object val = data.get(k);
            keyBuilder.append(val!=null?val:"").append("_");
        }
        return keyBuilder.toString();
    }

    //原有的map,新的map
    private void mergeData(Map oldData, Map newData, DataNode node, String parentKey){
        String existingChildKeyStr = keysMap.getFirst(parentKey);
        for (DataNode childNode : node.getSonDataNodes()){
            String nodeName = childNode.getNodeKey();
            Object childDataObj = oldData.get(nodeName);
            if (childNode.getNodeType()==1){
                Map childData = (Map) childDataObj;
                if (!StringUtils.hasText(existingChildKeyStr)){
                    existingChildKeyStr = buildKeyStr(childData,childNode);
                }
                mergeData(childData,(Map) (newData.get(nodeName)),childNode,parentKey+existingChildKeyStr);
            }else if (childNode.getNodeType()==2){
                List<Map> childDataList = (List<Map>) childDataObj;
                Map newChildData = ((List<Map>) newData.get(childNode.getNodeKey())).get(0);
                String newChildKeyStr = buildKeyStr(newChildData,childNode);
                boolean exists = false;
                if (!StringUtils.hasText(existingChildKeyStr)){
                    existingChildKeyStr = buildKeyStr(childDataList.get(0),childNode);
                }
                String tmpKey = parentKey + existingChildKeyStr;
                for (Map existingChildData : childDataList) {
                    if (existingChildKeyStr.equals(newChildKeyStr)){
                        mergeData(existingChildData,newChildData,childNode,tmpKey);
                        exists = true;
                        break;
                    }
                }
                if (!exists){
                    keysMap.add(parentKey,newChildKeyStr);
                    childDataList.add(newChildData);
                }
            }
        }
    }

}
